#include "logger.h"

#include "tools/ThreadEnumerator.h"
#include <boost/thread.hpp>

using namespace sd;
using namespace tools;
using namespace logger;





void logManager::init( std::wostream& defStream )
{
	boost::mutex::scoped_lock lock(mutex_);
	defStream_ = &defStream;
	thd_.swap( boost::thread( &logManager::workThread, this ) );
}


void logManager::map( int section, std::wostream& stream )
{
	boost::mutex::scoped_lock lock(mutex_);
	streams_.insert( std::make_pair( section, &stream ));
}


void logManager::log( const std::wstring& msg, int index )
{
	boost::mutex::scoped_lock lock(mutex_);
	list_.push_back( LogMsg(index, msg) );
}


static tools::thread::Thread createWaiter()
{
	tools::thread_enumerator::ProcessThreadEnumerator enumerator;

	tools::thread::Thread current;
	tools::thread::Thread waiter;	

	tools::thread_enumerator::ProcessThreadEnumerator::iterator it = enumerator.begin();
	do
	{
		waiter = *it;
	}while( waiter == current && (++it != enumerator.end()) );

	return waiter;
}

void logManager::workThread()
{
	tools::thread::Thread current;
	tools::thread::Thread waiter = createWaiter();
	while( waiter!=current )
	{
		{
			boost::mutex::scoped_lock lock(mutex_);
			for( int i=0; i < 100 && list_.size(); i++)
			{
				LogMsg msg = *list_.begin();
				Streams::iterator it = streams_.find( msg.first );
				if( it == streams_.end() )
					*defStream_ << msg.second << std::endl;
				else
					*it->second << msg.second << std::endl;
				
				list_.pop_front();
			}
		}

		if( waiter.timed_join( list_.size() ? 10 : 1000 ) ) 
			waiter = createWaiter();
	}
}